#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <string>

/******** 前缀和 差分 *********/
// 一维前缀和； 输出[l, r]区间所有元素的和
/*
const int N = 1e5 + 10;
int arr[N], dp[N];
//dp[i] = arr[1] + arr[2] + ... + arr[i]
//dp[i] = dp[i - 1] + arr[i]
int n, m;
int main()
{
    scanf("%d%d", &n, &m);
    //下面这段可以优化成一个循环
    // for(int i = 1; i <= n; ++i)
    //     scanf("%d", arr + i);
    // for(int i = 1; i <= n; ++i)
    //     dp[i] = dp[i - 1] + arr[i];
    for(int i = 1; i <= n; ++i)
    {
        int tmp;
        scanf("%d", &tmp);
        dp[i] = dp[i - 1] + tmp;
    }
    while(m--)
    {
        int l, r;
        scanf("%d%d", &l, &r);
        printf("%d\n", dp[r] - dp[l - 1]);
    }
    return 0;
}*/

// 二维前缀和：输出 (x1,y1) ~ (x2,y2) 矩形区域的和
// dp[i][j] 表示(0,0)~(i,j) 矩形区域的和
// dp[i][j] = dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1] + arr[i][j]
/*
int dp[1001][1001];
int n, m, q;
int main()
{
    scanf("%d %d %d", &n, &m, &q);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
        {
            scanf("%d", &dp[i][j]);
            dp[i][j] += dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1];
        }
    int x1, x2, y1, y2;
    while(q--)
    {
        scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
        printf("%d\n", dp[x2][y2] - dp[x2][y1 - 1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1]);
    }
    return 0;
}*/

// 一维差分：每次对区间[l, r]进行 + c操作，最后输出arr整个数组
// 构建arr[i] = dp[1] + dp[2] + ... + dp[i]
// 只需dp[l] + c, dp[r + 1] - c
// dp[i] = arr[i] - arr[i - 1]
// 但可以原地修改，原来每个数都是0，输入一个数arr[i]，就相当于对区间[i, i]进行 + arr[i]操作
/*
const int N = 1e5 + 10;
int arr[N], dp[N];
int n, m;
void add(int l, int r, int c)
{
    dp[l] += c, dp[r + 1] -= c
}
int main()
{
    scanf("%d %d", &n, &m);
    // for(int i = 1; i <= n; ++i)
    // {
    //     scanf("%d", arr + i);
    //     dp[i] = arr[i] - arr[i - 1];
    // }
    int tmp;
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d", &tmp);
        add(i, i, tmp);
    }
    int l, r, c;
    while(m--)
    {
        scanf("%d %d %d", &l, &r, &c);
        add(l, r, c);
    }
    // 由于arr[i] = dp[1] + dp[2] + ... + dp[i], 要还原arr
    for(int i = 1; i <= n; ++i)
    {
        dp[i] += dp[i - 1];
        printf("%d ", dp[i]);
    }
    return 0;
}*/

// 二维差分：每次对矩形区域 (x1,y1) ~ (x2,y2) 进行 + c操作，最后输出arr整个数组
// arr[i][j] 表示 [1,1] ~ [i,j] 矩形区域的dp和
/*
//int dp[1001][1001]; // 1 <= n,m <= 1000，dp[x2 + 1][y2 + 1] += c;当 n==1000 时，会越界
int dp[1010][1010];
int n, m, q;
void add(int x1, int y1, int x2, int y2, int c)
{
    dp[x1][y1] += c;
    dp[x1][y2 + 1] -= c;
    dp[x2 + 1][y1] -= c;
    dp[x2 + 1][y2 + 1] += c;
}
int main()
{
    scanf("%d%d%d", &n, &m, &q);
    int tmp, x1, y1, x2 ,y2, c;
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            scanf("%d", &tmp);
            add(i, j, i, j, tmp);
        }
    }
    while(q--)
    {
        scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &c);
        add(x1, y1, x2, y2, c);
    }
    //arr[i][j] = arr[i - 1][j] + arr[i][j - 1] - arr[i - 1][j - 1] + dp[i][j]
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= m; ++j)
        {
            dp[i][j] += dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];
            printf("%d\n", dp[i][j]);
        }
    }
    return 0;
}*/

/********** 双指针（滑动窗口） *********/
// 最长不重复子数组：
// 给定一个长度为 n的整数序列，请找出最长的不包含重复的数的连续区间，输出它的长度。
/*
const int N = 1e5 + 10;
int arr[N];
int ha[N];
int main()
{
    int n, ans = 1;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) scanf("%d", arr + i);
    int left = 0, right = 0;
    for (; right < n; ++right)
    {
        //当arr[right] 在前面已经出现过了， 就更新长度，左边出窗口
        if(ha[arr[right]])
        {
            ans = max(ans, right - left);
            while(ha[arr[right]])
                --ha[arr[left++]];
        }
        ++ha[arr[right]];
    }
    ans = max(ans, right - left);
    printf("%d", ans);
    return 0;
}*/

// 数组元素的目标和
// 给定两个升序排序的有序数组 A 和 B，以及一个目标值 x。请你求出满足 A[i] + B[j] = x的数对(i, j)
/*
const int N = 1e5 + 10;
int a[N], b[N];
int n, m, x;
int main()
{
    scanf("%d %d %d", &n, &m, &x);
    for (int i = 0; i < n; ++i)
        scanf("%d", a + i);
    for (int i = 0; i < m; ++i)
        scanf("%d", b + i);
    for (int i = 0, j = m - 1; i < n && j >= 0;)
    {
        // a[i] 是最小的，b[j]是最大的。最大的配最小的都还大，那b[j] 配别的也一定大，就不需要考虑b[j]了
        if (a[i] + b[j] > x)
            --j;
        // a[i] 是最小的，b[j]是最大的。最小的配最大的都还小，那a[i] 配别的也一定小，就不需要考虑a[i]了
        else if (a[i] + b[j] < x)
            ++i;
        else
        {
            printf("%d %d", i, j);
            break;
        }
    }
    return 0;
}*/

// 判断子序列
/*
const int N = 1e5 + 10;
int a[N], b[N];
int n, m;
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; ++i)
        scanf("%d", a + i);
    for (int i = 0; i < m; ++i)
        scanf("%d", b + i);
    int i = 0, j = 0;
    for (; i < n && j < m;)
    {
        // 不相等，j往后走；相等，一起往后走
        if (b[j] != a[i])
            ++j;
        else
            ++i, ++j;
    }
    if (i < n)
        puts("No");
    else
        puts("Yes");
    return 0;
}*/

/************ 位运算 ***********/
// 拿掉最低位的1：a & (a - 1)，或者 a - (a & -a)
// 求最低位的1：a & (-a)
// 求n的第k位二进制：(n >> k) & 1 （k从0开始）
/*
const int N = 1e5 + 10;
int arr[N];
int n;
int main()
{
    scanf("%d", &n);
    for(int i = 0; i < n; ++i)
        scanf("%d", arr + i);
    for(int i = 0; i < n; ++i)
    {
        int c = 0;
        while(arr[i])
        {
            ++c;
            arr[i] &= arr[i] - 1;
        }
        printf("%d ", c);
    }
    return 0;
}*/

/*************** 离散化 *************/
/*
假定有一个无限长的数轴，数轴上每个坐标上的数都是 0。
现在，我们首先进行 n 次操作，每次操作将某一位置 x 上的数加 c
接下来，进行 m 次询问，每个询问包含两个整数 l 和 r ，你需要求出在区间 [l,r] 之间的所有数的和。
*/
// nums 值域很大，但nums.size()较小
// 可以将nums排好序，把所有的数映射到 1 ~ n，再用前缀和
// a1   a2   ...  an
//  1    2         n
// 映射完后，我们还需要知道ai对应的是哪个下标，可以考虑用二分

/*
vector<pair<int, int>> op;
vector<pair<int, int>> q;
int ha[300010], arr[300010], idx = 1;
int find(int k)
{
    int l = 1, r = idx - 1;
    while (l < r)
    {
        int mid = (l + r) >> 1;
        if (ha[mid] < k)
            l = mid + 1;
        else
            r = mid;
    }
    return l;
}
int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    op.reserve(n);
    q.reserve(m);
    // 每个位置映射到 1 ~ idx
    int x, c;
    while (n--)
    {
        scanf("%d %d", &x, &c);
        op.push_back({x, c});
        ha[idx++] = x;
    }
    int l, r;
    while (m--)
    {
        scanf("%d %d", &l, &r);
        q.push_back({l, r});
        ha[idx++] = l;
        ha[idx++] = r;
    }
    // 排序+去重
    // vector做法：sort(ha.begin(),ha.end()); ha.erase(unique(ha.begin(),ha.end()));
    sort(ha + 1, ha + idx);
    int i = 2, j = 2;
    for (; j < idx; ++j)
    {
        if (ha[j] != ha[j - 1])
            ha[i++] = ha[j];
    }
    idx = i;
    // 操作
    for (auto [x, c] : op)
    {
        int i = find(x);
        arr[i] += c;
    }
    // 前缀和
    for (int i = 1; i < idx; ++i)
        arr[i] += arr[i - 1];
    for (auto [l, r] : q)
        printf("%d\n", arr[find(r)] - arr[find(l) - 1]);
    return 0;
}*/

/********** 区间合并 **********/
vector<pair<int, int>> merge(vetor<pair<int, int>> &v)
{
    // 按左端点排序，每次只考虑前面区间最右侧端点是否跟当前区间右交集
    // 没有交集时，说明前面的合并完毕，需要再维护当前区间
    vector<pair<int, int>> ans;
    sort(v.begin(), v.end());
    auto [start, end] = v[0];
    for (auto [l, r] : v)
    {
        if (l > end)
            ans.push_back({start, end});
        end = max(end, r);
    }
    ans.push_back({start, end});
    return ans;
}
int main()
{
    int n;
    scanf("%d", &n);
    vector<pair<int, int>> v;
    v.reserve(n);
    int l, r;
    while (n--)
    {
        scanf("%d %d", &l, &r);
        v.push_back({l, r});
    }
    sort(v.begin(), v.end());
    int pre = v[0].first, c = 0;
    for (auto [le, ri] : v)
    {
        // if(le > pre)
        // {
        //     ++c;
        //     pre = ri;
        // }
        // else
        // {
        //     if(ri > pre)
        //         pre = ri;
        // }
        if (le > pre)
            ++c;
        pre = max(ri, pre);
    }
    // 最后一个区间还没算
    printf("%d", c + 1);
    return 0;
}

// 例题：759格子染色